import React, {
  useEffect,
  useRef,
  useState,
  forwardRef,
  useImperativeHandle,
} from "react";
import "./Earth3D.css";
import { EarthGlobe } from "./EarthGlobe";
import {
  LatLngPoint,
  LatLngPolygon,
  LatLngRect,
  LocationPoint,
  DetectionPoint,
} from "../types/earth";

interface Earth3DProps {
  polygons?: LatLngPolygon[];
  dataAreas?: LatLngRect[];
  patrolAreas?: LatLngRect[]; // 新增巡视区数据
  locationPoints?: LocationPoint[];
  detectionPoints?: DetectionPoint[]; // 新增探测点数据
  radius: number;
  tileUrlTemplate?: string;
  modelUrl?: string;
  maxZoom?: number; // 新增maxZoom参数
  onHover?: (coord: LatLngPoint | null) => void;
  onClick?: (coord: LatLngPoint | null) => void;
  onLocationHover?: (location: LocationPoint | null) => void;
  onLocationClick?: (location: LocationPoint | null) => void;
  onDetectionPointHover?: (detectionPoint: DetectionPoint | null) => void; // 新增探测点悬停回调
  onDetectionPointClick?: (detectionPoint: DetectionPoint | null) => void; // 新增探测点点击回调
  onPatrolAreaClick?: (patrolArea: LatLngRect | null) => void; // 新增巡视区点击回调
  onPatrolAreaHover?: (patrolArea: LatLngRect | null) => void; // 新增巡视区悬停回调
  onSelectionChange?: (selectionRect: LatLngRect | null) => void; // 选区变化回调
  onSelectionEnd?: (
    selectionRect: LatLngRect | null,
    intersectingRects: LatLngRect[],
    intersectingDetectionPoints: DetectionPoint[]
  ) => void; // 选区结束回调
  externalSelection?: LatLngRect | null; // 外部传入的选区状态
  simulatedMetaKey?: boolean; // 模拟Meta键状态
}

// 定义暴露的方法接口
export interface EarthCanvasRef {
  zoomIn: () => void;
  zoomOut: () => void;
  resetView: () => void;
  getCameraZ: () => number;
  setCameraZ: (z: number) => void;
  enterSelectionMode: () => void;
  exitSelectionMode: () => void;
  clearSelection: () => void;
}

const Earth3D = forwardRef<EarthCanvasRef, Earth3DProps>(
  (
    {
      polygons,
      dataAreas,
      patrolAreas = [], // 新增巡视区数据
      locationPoints = [],
      detectionPoints = [], // 新增
      radius,
      tileUrlTemplate = "/earth_tiles/{z}_{y}_{x}.jpg",
      modelUrl,
      maxZoom = 5, // 新增maxZoom参数，默认值为5
      onHover,
      onClick,
      onLocationHover,
      onLocationClick,
      onDetectionPointHover, // 新增
      onDetectionPointClick, // 新增
      onPatrolAreaClick, // 新增巡视区点击回调
      onPatrolAreaHover, // 新增巡视区悬停回调
      onSelectionChange,
      onSelectionEnd,
      externalSelection,
      simulatedMetaKey = false,
    },
    ref
  ) => {
    const mountRef = useRef<HTMLDivElement>(null);
    const globeRef = useRef<EarthGlobe | null>(null);
    const [scalePx, setScalePx] = useState(100);
    const [scaleLength, setScaleLength] = useState(1000);
    const [hoverCoord, setHoverCoord] = useState<LatLngPoint | null>(null);
    const [clickedCoord, setClickedCoord] = useState<LatLngPoint | null>(null);
    const [cameraZ, setCameraZ] = useState(3); // 新增
    const [zoomLevel, setZoomLevel] = useState(1); // 新增
    const [visibleTileKeys, setVisibleTileKeys] = useState<string[]>([]);
    const [memoryInfo, setMemoryInfo] = useState({
      tileCount: 0,
      textureCount: 0,
      visibleTiles: 0,
    }); // 新增
    const minZoom = 1;

    useImperativeHandle(ref, () => ({
      zoomIn: () => {
        if (globeRef.current) {
          globeRef.current.zoomIn();
        }
      },
      zoomOut: () => {
        if (globeRef.current) {
          globeRef.current.zoomOut();
        }
      },
      resetView: () => {
        if (globeRef.current) {
          globeRef.current.resetView();
        }
      },
      getCameraZ: () => {
        return cameraZ;
      },
      setCameraZ: (z: number) => {
        setCameraZ(z);
        if (globeRef.current) {
          globeRef.current.setCameraZ(z);
        }
      },
      enterSelectionMode: () => {
        if (globeRef.current) {
          globeRef.current.enterSelectionMode();
        }
      },
      exitSelectionMode: () => {
        if (globeRef.current) {
          globeRef.current.exitSelectionMode();
        }
      },
      clearSelection: () => {
        if (globeRef.current) {
          globeRef.current.clearSelection();
        }
      },
    }));

    useEffect(() => {
      if (mountRef.current) {
        globeRef.current = new EarthGlobe(mountRef.current, {
          radius,
          modelUrl,
          locationPoints,
          detectionPoints, // 新增
          onHover: (coord) => {
            setHoverCoord(coord);
            onHover?.(coord);
          },
          onClick: (coord) => {
            setClickedCoord(coord);
            onClick?.(coord);
          },
          onLocationHover: (location) => {
            onLocationHover?.(location);
          },
          onLocationClick: (location) => {
            onLocationClick?.(location);
          },
          onDetectionPointHover: (detectionPoint) => {
            // 新增
            onDetectionPointHover?.(detectionPoint);
          },
          onDetectionPointClick: (detectionPoint) => {
            // 新增
            onDetectionPointClick?.(detectionPoint);
          },
          onPatrolAreaClick: (patrolArea) => {
            // 新增巡视区点击回调
            onPatrolAreaClick?.(patrolArea);
          },
          onPatrolAreaHover: (patrolArea) => {
            // 新增巡视区悬停回调
            onPatrolAreaHover?.(patrolArea);
          },
          onSelectionChange: (selectionRect) => {
            onSelectionChange?.(selectionRect);
          },
          onSelectionEnd: (
            selectionRect,
            intersectingRects,
            intersectingDetectionPoints
          ) => {
            onSelectionEnd?.(
              selectionRect,
              intersectingRects,
              intersectingDetectionPoints
            );
          },
          tileUrlTemplate,
          minZoom,
          maxZoom,
          onZoomChange: (z, level) => {
            // 使用防抖机制避免频繁更新
            setCameraZ((prevZ) => {
              if (Math.abs(prevZ - z) > 0.01) {
                return z;
              }
              return prevZ;
            });
            setZoomLevel((prevLevel) => {
              if (prevLevel !== level) {
                return level;
              }
              return prevLevel;
            });
          },
          simulatedMetaKey,
        });
        // 挂载到window，方便控制台调试
        window.globe = globeRef.current;
      }
      return () => {
        globeRef.current?.dispose();
        globeRef.current = null;
        if (window.globe) {
          delete window.globe;
        }
      };
    }, [radius, tileUrlTemplate, modelUrl, maxZoom]); // 添加maxZoom依赖，确保maxZoom变化时重新初始化

    useEffect(() => {
      if (globeRef.current && polygons) {
        globeRef.current.setPolygons(polygons);
      }
    }, [polygons]);

    useEffect(() => {
      if (globeRef.current && dataAreas) {
        globeRef.current.setRects(dataAreas);
      }
    }, [dataAreas]);

    // 更新巡视区数据
    useEffect(() => {
      if (globeRef.current && patrolAreas) {
        globeRef.current.setPatrolAreas(patrolAreas);
      }
    }, [patrolAreas]);

    // 更新模拟Meta键状态
    useEffect(() => {
      if (globeRef.current) {
        globeRef.current.setSimulatedMetaKey(simulatedMetaKey);
      }
    }, [simulatedMetaKey]);

    useEffect(() => {
      if (globeRef.current && locationPoints) {
        globeRef.current.setLocationPoints(locationPoints);
      }
    }, [locationPoints]);

    useEffect(() => {
      if (globeRef.current && detectionPoints) {
        // 新增
        globeRef.current.setDetectionPoints(detectionPoints);
      }
    }, [detectionPoints]);

    useEffect(() => {
      if (globeRef.current) {
        globeRef.current.setExternalSelection(externalSelection || null);
      }
    }, [externalSelection]);

    // 关闭浮窗
    const handleCloseModal = () => {
      // 移除内部状态管理，由父组件统一管理
    };

    // 定时刷新比例尺 - 降低更新频率以避免无限循环
    useEffect(() => {
      let animId: number;
      let isActive = true;
      let lastUpdateTime = 0;
      const UPDATE_INTERVAL = 500; // 每500ms更新一次，进一步降低频率

      // 缓存上一次的值，避免不必要的状态更新
      let lastScalePx = 100;
      let lastScaleLength = 1000;
      let lastVisibleTileKeys: string[] = [];
      let lastMemoryInfo = { tileCount: 0, textureCount: 0, visibleTiles: 0 };

      const updateScale = () => {
        if (!isActive) {
          return;
        }

        const now = Date.now();
        if (now - lastUpdateTime < UPDATE_INTERVAL) {
          // 如果距离上次更新时间太短，跳过这次更新
          animId = requestAnimationFrame(updateScale);
          return;
        }

        try {
          if (globeRef.current) {
            const scaleInfo = globeRef.current.getScaleInfo();
            if (
              scaleInfo &&
              typeof scaleInfo.px === "number" &&
              typeof scaleInfo.km === "number"
            ) {
              // 只有当值真正改变时才更新状态
              if (
                Math.abs(scaleInfo.px - lastScalePx) > 1 ||
                Math.abs(scaleInfo.km - lastScaleLength) > 10
              ) {
                setScalePx(scaleInfo.px);
                setScaleLength(scaleInfo.km);
                lastScalePx = scaleInfo.px;
                lastScaleLength = scaleInfo.km;
              }
            }

            // 新增：定时刷新可见tile key
            if (typeof globeRef.current.getVisibleTileKeys === "function") {
              const tileKeys = globeRef.current.getVisibleTileKeys();
              if (Array.isArray(tileKeys)) {
                // 只有当tile keys真正改变时才更新状态
                const tileKeysStr = tileKeys.join(",");
                const lastTileKeysStr = lastVisibleTileKeys.join(",");
                if (tileKeysStr !== lastTileKeysStr) {
                  setVisibleTileKeys(tileKeys);
                  lastVisibleTileKeys = [...tileKeys];
                }
              }
            }

            // 新增：定时刷新内存信息
            if (typeof globeRef.current.getMemoryInfo === "function") {
              const memory = globeRef.current.getMemoryInfo();
              if (memory && typeof memory === "object") {
                // 只有当内存信息真正改变时才更新状态
                const memoryStr = JSON.stringify(memory);
                const lastMemoryStr = JSON.stringify(lastMemoryInfo);
                if (memoryStr !== lastMemoryStr) {
                  setMemoryInfo(memory);
                  lastMemoryInfo = { ...memory };
                }
              }
            }
          }
        } catch (error) {
          console.warn("更新比例尺时出错:", error);
        }

        lastUpdateTime = now;

        // 继续下一帧的更新
        if (isActive) {
          animId = requestAnimationFrame(updateScale);
        }
      };

      // 开始动画循环
      animId = requestAnimationFrame(updateScale);

      // 清理函数
      return () => {
        isActive = false;
        if (animId) {
          cancelAnimationFrame(animId);
        }
      };
    }, []);

    return (
      <div
        ref={mountRef}
        className="earth-canvas-root"
        style={{
          cursor: simulatedMetaKey ? "crosshair" : "grab",
        }}
      >
        <div
          style={{
            display: "none",
            position: "absolute",
            top: 100,
            left: 10,
            background: "rgba(0,0,0,0.5)",
            color: "#fff",
            padding: "4px 10px",
            borderRadius: 4,
            fontSize: 14,
            zIndex: 10,
          }}
        >
          z: {cameraZ.toFixed(2)}
          <br />
          level: {zoomLevel}
          <br />
          瓦片数: {memoryInfo.tileCount}
          <br />
          纹理数: {memoryInfo.textureCount}
          <br />
          可见瓦片: {memoryInfo.visibleTiles}
          <div style={{ marginTop: 8 }}>
            <div>当前显示的tile key：</div>
            <ul
              style={{
                maxHeight: 120,
                overflow: "auto",
                fontSize: 12,
                margin: 0,
                padding: 0,
                listStyle: "none",
              }}
            >
              {visibleTileKeys.map((key) => (
                <li key={key}>{key}</li>
              ))}
            </ul>
          </div>
          <div style={{ marginTop: 8 }}>
            <button
              onClick={() => globeRef.current?.clearTextureCache()}
              style={{
                background: "#ff4444",
                color: "#fff",
                border: "none",
                padding: "2px 6px",
                borderRadius: 3,
                fontSize: 12,
                cursor: "pointer",
              }}
            >
              清理纹理缓存
            </button>
          </div>
        </div>
        <div
          className="earth-scale-bar"
          style={{ "--scale-bar-width": scalePx + "px" } as React.CSSProperties}
        >
          <span style={{ marginLeft: 8 }}>{scaleLength} km</span>
        </div>
      </div>
    );
  }
);

export default Earth3D;
